#include "systemdata.h"
#include "24Cxx.h"
#include <stdio.h>
#include "drv_rtc.h"
#include "drv_timer.h"
#include "tsdb_save_data.h"

//AT24C08共1K字节，前512字节用于存储系统配置信息，后512用于存储系统故障信息

#define XG_SETTINGS_START_ADDR   0x0000
#define XG_ERRRECORD_START_ADDR  0x0200

	

static SysRunData_t runData;
static SysConfData_t confData,oldConfData;
static XgErrRecord    xgErrorInfo;


SysRunData_t *getSysRunData(void){
	return &runData;
}

SysConfData_t *getSysConfData(void){
	return &confData;
}

static void loadDefaultConfData(void){//加载默认参数
	memset((char *)&confData,0,sizeof(SysConfData_t));
	/////////////////////////出厂参数
	confData.fctData.batType = 0x01;
	confData.fctData.batNum = 17;
	strcpy((char *)confData.fctData.hdSerial,"xg123456");
	strcpy((char *)confData.fctData.BtNum,"BT3072020120000200521001");
	confData.fctData.normalCap.value = 200;
	confData.fctData.realCap.value = 200;
	confData.fctData.cycleTimes.value = 0;
	confData.fctData.preChargeTime.value = 100;
	confData.fctData.poweroff_vol.value = 2900;//默认关机电压
	confData.fctData.wakeupCurrent.value = 100;
	confData.fctData.otherParmByte.bit.key_check_enable = 0;
	confData.fctData.otherParmByte.bit.chag_pwr_prchg_enable = 0;

	/////////////////////////告警参数
	confData.warnData.batVolHigh.value = 4000;
	confData.warnData.batVolLow.value = 3000;
	confData.warnData.batVolDiff.value = 100;
	confData.warnData.packVolHigh.value = 680;
	confData.warnData.packVolLow.value = 510;
	
	confData.warnData.mosTempHigh = 60;
	confData.warnData.envTempHigh = 50;
	confData.warnData.envTemplow = -5;
	confData.warnData.chgTempHigh = 50;
	confData.warnData.chgTempLow = -5;
	confData.warnData.dsgTempHigh = 50;
	confData.warnData.dsgTempLow = -10;
	confData.warnData.socLow = 15;	
	
	/////////////////////////保护参数
	confData.errorData.batVolHigh.value = 4230;
	confData.errorData.batVolHighRecover.value = 4100;
	confData.errorData.batVolHighTime = 3;
	
	confData.errorData.batVolLow.value = 2800;
	confData.errorData.batVolLowRecover.value = 3300;
	confData.errorData.batVolLowTime = 3;
	
	confData.errorData.sov_vol.value = 4250;
	confData.errorData.suv_vol.value = 2750;
	confData.errorData.sov_suv_dly_s = 3;

	confData.errorData.batVolDiff.value = 200;
	confData.errorData.batVolDiffRecover.value = 100;
	confData.errorData.batVolDiffTime = 3;
	
	confData.errorData.packVolHigh.value = 719;
	confData.errorData.packVolHighRecover.value = 697;
	confData.errorData.packVolHighTime = 3;
	
	confData.errorData.packVolLow.value = 476;
	confData.errorData.packVolLowRecover.value = 561;
	confData.errorData.packVolLowTime = 3;

	confData.errorData.mosTempHigh = 70;
	confData.errorData.mosTempHighRecover = 50;
	confData.errorData.mosTempHighTime = 5;
	
	confData.errorData.envTempHigh = 60;
	confData.errorData.envTempHighRecover = 50;
	confData.errorData.envTempHighTime = 5;
	
	confData.errorData.envTempLow = -10;
	confData.errorData.envTempLowRecover = 0;
	confData.errorData.envTempLowTime = 5;

	confData.errorData.chgTempHigh = 70;
	confData.errorData.chgTempHighRecover = 50;
	confData.errorData.chgTempHighTime = 5;
	
	confData.errorData.chgTempLow = -10;
	confData.errorData.chgTempLowRecover = 0;
	confData.errorData.chgTempLowTime = 5;
	
	confData.errorData.dsgTempHigh = 70;
	confData.errorData.dsgTempHighRecover = 50;
	confData.errorData.dsgTempHighTime = 5;
	
	confData.errorData.dsgTempLow = -10;
	confData.errorData.dsgTempLowRecover = 0;
	confData.errorData.dsgTempLowTime = 5;
	
	confData.errorData.batTempDiff = 20;
	confData.errorData.batTempDiffRecover = 10;
	confData.errorData.batTempDiffTime = 5;
	
	confData.errorData.chgOverCurrent.value = 20;
	confData.errorData.chgOverCurRecoverTime.value = 60;
	confData.errorData.chgOverCurrentTime = 5;
	
	confData.errorData.chgOverCurrent2.value = 30;
	confData.errorData.chgOverCur2RecoverTime.value = 60;
	confData.errorData.chgOverCurrent2Time =3;
	
	confData.errorData.chgOverCurrent3.value = 50;
	confData.errorData.chgOverCur3RecoverTime.value = 60;
	confData.errorData.chgOverCurrent3Time = 2;
			
	confData.errorData.dsgOverCurrent.value = 60;
	confData.errorData.dsgOverCurRecoverTime.value = 60;
	confData.errorData.dsgOverCurrentTime = 5;
	
	confData.errorData.dsgOverCurrent2.value = 80;
	confData.errorData.dsgOverCur2RecoverTime.value = 60;
	confData.errorData.dsgOverCurrent2Time = 5;
	
	confData.errorData.dsgOverCurrent3.value = 90;
	confData.errorData.dsgOverCur3RecoverTime.value = 60;
	confData.errorData.dsgOverCurrent3Time = 5;
	
	confData.errorData.dsgOverCurrent4.value = 100;
	confData.errorData.dsgOverCur4RecoverTime.value = 60;
	confData.errorData.dsgOverCurrent4Time.value = 1280;
	
	confData.errorData.scdVol.value = 100;	
	confData.errorData.scdRecoverTime.value = 60;
	confData.errorData.scdVolTime.value = 400;
	
	confData.errorData.disOverCurLockTimes.value = 0;
	confData.errorData.chgOverCurLockTimes.value = 0;
	confData.errorData.scdLockTimes.value = 0;
	
	/////////////////////////均衡参数
	confData.balData.endDiffVol.value = 15;//被动均衡
	confData.balData.openVol.value = 3600;
	confData.balData.openDiffVol.value = 30;
	
	/////////////////////////校准参数
	confData.caliData.curRadio = 10000;
	confData.caliData.lowAdcRadio = 10000;
	confData.caliData.highAdcRadio = 10000;
	
	/////////////////////////至想参数
	confData.zhixiangParam.devAddr = 0x01;
	confData.zhixiangParam.serialPortBaudRate.value = 96;//用作串口时,乘以100
	
	memcpy(&oldConfData,&confData,sizeof(SysConfData_t));
	AT24CXX_Write(XG_SETTINGS_START_ADDR,(uint8_t *)&confData,sizeof(SysConfData_t));
}

void loadXgErrRecordInfo(void){
	AT24CXX_Read(XG_ERRRECORD_START_ADDR,(uint8_t *)&xgErrorInfo,sizeof(XgErrRecord));
	uint16_t i = 0;
	uint8_t *p = (uint8_t *)&xgErrorInfo;
}

void loadXgSystemParam(void){
	if(AT24CXX_ReadOneByte(AT24C08-1) == 0xBB){
		AT24CXX_Read(XG_SETTINGS_START_ADDR,(uint8_t *)&confData,sizeof(SysConfData_t));
		if(confData.caliData.curRadio >= 15000 || confData.caliData.curRadio <= 5000){
			confData.caliData.curRadio = 10000;
			saveSysConfData();
		}
		if(confData.fctData.batNum > 24 || confData.fctData.batNum < 1){
			loadDefaultConfData();
			sysErrRcdClear();	
		}
		saveSysConfData();
		memcpy(&oldConfData,&confData,sizeof(SysConfData_t));
	}else{
		loadDefaultConfData();
		sysErrRcdClear();
		AT24CXX_WriteOneByte(AT24C08-1,0XBB);
	}
	memset(&runData,0,sizeof(runData));
	runData.funcSwState.bits.SW_BL_EN = confData.balData.allowCtrl;
	loadXgErrRecordInfo();
}

void saveSysConfData(void){

	uint8_t *pNew = (uint8_t *)&confData;
	uint8_t *pOld = (uint8_t *)&oldConfData;
	for(uint16_t i = 0;i<sizeof(SysConfData_t);i++){
		if(pOld[i] != pNew[i]){
			pOld[i] = pNew[i];
			AT24CXX_WriteOneByte(i,pNew[i]);
		}
	}
	///////////////////////////////
	uint8_t read_buf[sizeof(SysConfData_t)];
	AT24CXX_Read(XG_SETTINGS_START_ADDR,read_buf,sizeof(SysConfData_t));
//	printf("read EEPROM \n");
//	for(uint16_t j=0;j<sizeof(SysConfData_t);j++){
//		printf("%02x,",read_buf[j]);
//	}
//	printf("\n");
}

void sysErrRcdClear(void){
	xgErrorInfo.recordNum = 30;
	uint8_t i = 0;
	for(i=0;i<xgErrorInfo.recordNum ;i++){
		xgErrorInfo.recordData[i].errorCode = i+1;
		xgErrorInfo.recordData[i].occurTimes = 0;
		memset(xgErrorInfo.recordData[i].latestOccurTime,'-',6);
	}
	AT24CXX_Write(XG_ERRRECORD_START_ADDR,(uint8_t *)&xgErrorInfo,sizeof(XgErrRecord));
}

XgErrRecord *getSysErrRcdInfo(void){
	return &xgErrorInfo;
}

//保存某一故障特定的数据
void saveErrSpecifyparam(unsigned char *paramAddress,unsigned char paramSize){
	XgErrorData errData;
	unsigned char *xgparam = (unsigned char *)&xgErrorInfo;
	unsigned char addressOffet = paramAddress - xgparam;
	AT24CXX_Write(XG_ERRRECORD_START_ADDR+addressOffet,(uint8_t *)paramAddress,paramSize);
}

static void saveErrorRecord(XgErrorCode errorCode){
	xgErrorInfo.recordData[errorCode-1].errorCode = errorCode;
	xgErrorInfo.recordData[errorCode-1].occurTimes ++;	
	getRtcTimeHex((char *)&xgErrorInfo.recordData[errorCode - 1].latestOccurTime);
	saveErrSpecifyparam((uint8_t *)&xgErrorInfo.recordData[errorCode-1],sizeof(xgErrorInfo.recordData[errorCode-1]));
}




void saveSystemErrorRecord(void){
	//检测故障位是否发生变化，然后保存故障记录	
	static XgVolProtByte    lastVolErrCode = {.volProt.byte = 0};
	static XgTempProtByte   lastTempErrCode = {.byte = 0};
	static XgCurProtByte    lastCurErrCode = {.byte = 0};
	static XgAfeProtByte    lastAfeErrCode = {.byte = 0};

	static bool lastbatVolHgProt = false;
	static bool runbatVolHgProt = false;
	static bool lastbatVolLowProt = false;
	static bool runbatVolLowProt = false;
	lastbatVolHgProt = (bool)lastVolErrCode.cellHgVolProt;
	runbatVolHgProt = (bool)runData.volProtByte.cellHgVolProt;
	lastbatVolLowProt = (bool)lastVolErrCode.cellLowVolProt;
	runbatVolLowProt = (bool)runData.volProtByte.cellLowVolProt;

	if(lastbatVolHgProt != runbatVolHgProt){
		lastVolErrCode.cellHgVolProt = runData.volProtByte.cellHgVolProt;
		if(runbatVolHgProt == 1){
			printf("save SOV over error\n");
			saveErrorRecord(sbatOvCode);
			append_alarm_prot_record();
		}
	}
	
	if(lastbatVolLowProt != runbatVolLowProt){
		lastVolErrCode.cellLowVolProt = runData.volProtByte.cellLowVolProt;
		if(runbatVolLowProt == 1){
			printf("save SUV over error\n");
			saveErrorRecord(sbatUvCode);
			append_alarm_prot_record();
		}
	}
	
	if(lastVolErrCode.volProt.bit.afeVolHgProt != runData.volProtByte .volProt.bit.afeVolHgProt){
		lastVolErrCode.volProt.bit.afeVolHgProt = runData.volProtByte .volProt.bit.afeVolHgProt;
		if(runData.volProtByte.volProt.bit.afeVolHgProt == 1){
			printf("save afe SOV error\n");
			saveErrorRecord(afebatOvCode);
			append_alarm_prot_record();
		}
	}
	
	if(lastVolErrCode.volProt.bit.afeVolLowProt != runData.volProtByte .volProt.bit.afeVolLowProt){
		lastVolErrCode.volProt.bit.afeVolLowProt = runData.volProtByte .volProt.bit.afeVolLowProt;
		if(runData.volProtByte.volProt.bit.afeVolLowProt == 1){
			printf("save afe SUV error\n");
			saveErrorRecord(afebatUvCode);
			append_alarm_prot_record();
		}
	}
	
	if(lastVolErrCode.volProt.bit.packVolHgProt != runData.volProtByte.volProt.bit.packVolHgProt){
		lastVolErrCode.volProt.bit.packVolHgProt = runData.volProtByte.volProt.bit.packVolHgProt;
		if(runData.volProtByte.volProt.bit.packVolHgProt == 1){
			printf("save POV over error\n");
			saveErrorRecord(packOvCode);
			append_alarm_prot_record();
		}
	}
	if(lastVolErrCode.volProt.bit.packVolLowProt != runData.volProtByte.volProt.bit.packVolLowProt){
		lastVolErrCode.volProt.bit.packVolLowProt = runData.volProtByte.volProt.bit.packVolLowProt;
		if(runData.volProtByte.volProt.bit.packVolLowProt == 1){
			printf("save PUV over error\n");
			saveErrorRecord(packUvCode);
			append_alarm_prot_record();
		}
	}
	
	if(lastVolErrCode.volProt.bit.cellVolDiffProt != runData.volProtByte.volProt.bit.cellVolDiffProt){
		lastVolErrCode.volProt.bit.cellVolDiffProt = runData.volProtByte.volProt.bit.cellVolDiffProt;
		if(runData.volProtByte.volProt.bit.cellVolDiffProt == 1){
			printf("save vol diff over error\n");
			saveErrorRecord(sbatDifCode);
			append_alarm_prot_record();
		}
	}
		
	if(lastTempErrCode.bit.envTempHgProt != runData.tempProtByte.bit.envTempHgProt){
		lastTempErrCode.bit.envTempHgProt = runData.tempProtByte.bit.envTempHgProt;
		if(runData.tempProtByte.bit.envTempHgProt == 1){
			printf("save envTemp Hg over error\n");
			saveErrorRecord(envOtCode);
			append_alarm_prot_record();
		}
	}
	
	if(lastTempErrCode.bit.envTempLowProt != runData.tempProtByte.bit.envTempLowProt){
		lastTempErrCode.bit.envTempLowProt = runData.tempProtByte.bit.envTempLowProt;
		if(runData.tempProtByte.bit.envTempLowProt == 1){
			printf("save envTemp Low over error\n");
			saveErrorRecord(envUtCode);
			append_alarm_prot_record();
		}
	}
	
	if(lastTempErrCode.bit.chgTempLowProt != runData.tempProtByte.bit.chgTempLowProt){
		lastTempErrCode.bit.chgTempLowProt = runData.tempProtByte.bit.chgTempLowProt;
		if(runData.tempProtByte.bit.chgTempLowProt == 1){
			printf("save CHG_UT over error\n");
			saveErrorRecord(batChgUtCode);
			append_alarm_prot_record();
		}
	}
	if(lastTempErrCode.bit.chgTempHgProt != runData.tempProtByte.bit.chgTempHgProt){
		lastTempErrCode.bit.chgTempHgProt = runData.tempProtByte.bit.chgTempHgProt;
		if(runData.tempProtByte.bit.chgTempHgProt == 1){
			printf("save CHG_OT over error\n");
			saveErrorRecord(batChgOtCode);
			append_alarm_prot_record();
		}
	}
	if(lastTempErrCode.bit.disTempLowProt != runData.tempProtByte.bit.disTempLowProt){
		lastTempErrCode.bit.disTempLowProt = runData.tempProtByte.bit.disTempLowProt;
		if(runData.tempProtByte.bit.disTempLowProt == 1){
			printf("save DSG_UT over error\n");
			saveErrorRecord(batDsgUtCode);
			append_alarm_prot_record();
		}
	}
	if(lastTempErrCode.bit.disTempHgProt != runData.tempProtByte.bit.disTempHgProt){
		lastTempErrCode.bit.disTempHgProt = runData.tempProtByte.bit.disTempHgProt;
		if(runData.tempProtByte.bit.disTempHgProt == 1){
			printf("save DSG_OT over error\n");
			saveErrorRecord(batDsgOtCode);
			append_alarm_prot_record();
		}
	}
	
	if(lastTempErrCode.bit.tempDiffProt != runData.tempProtByte.bit.tempDiffProt){
		lastTempErrCode.bit.tempDiffProt = runData.tempProtByte.bit.tempDiffProt;
		if(runData.tempProtByte.bit.tempDiffProt == 1){
			printf("save Temp diff over error\n");
			saveErrorRecord(tempDiffCode);
			append_alarm_prot_record();
		}
	}
		
	
	if(lastTempErrCode.bit.mosTempHgProt != runData.tempProtByte.bit.mosTempHgProt){
		lastTempErrCode.bit.mosTempHgProt = runData.tempProtByte.bit.mosTempHgProt;
		if(runData.tempProtByte.bit.mosTempHgProt == 1){
			printf("save MOS_OT over error\n");
			saveErrorRecord(mosOtCode);
			append_alarm_prot_record();
		}
	}
	if(lastCurErrCode.bit.chgCur3Prot != runData.curProtByte.bit.chgCur3Prot){
		lastCurErrCode.bit.chgCur3Prot = runData.curProtByte.bit.chgCur3Prot;
		if(runData.curProtByte.bit.chgCur3Prot == 1){
			printf("save CHGOCD3 over error\n");
			saveErrorRecord(chgOcd3Code);
			append_alarm_prot_record();
		}
	}
	if(lastCurErrCode.bit.chgCur2Prot != runData.curProtByte.bit.chgCur2Prot){
		lastCurErrCode.bit.chgCur2Prot = runData.curProtByte.bit.chgCur2Prot;
		if(runData.curProtByte.bit.chgCur2Prot == 1){
			printf("save CHGOCD2 over error\n");
			saveErrorRecord(chgOcd2Code);
			append_alarm_prot_record();
		}
	}
	if(lastCurErrCode.bit.chgCUr1Prot != runData.curProtByte.bit.chgCUr1Prot){
		lastCurErrCode.bit.chgCUr1Prot = runData.curProtByte.bit.chgCUr1Prot;
		if(runData.curProtByte.bit.chgCUr1Prot == 1){
			printf("save CHGOCD over error\n");
			saveErrorRecord(chgOcdCode);
			append_alarm_prot_record();
		}
	}
	if(lastCurErrCode.bit.disCur1Prot != runData.curProtByte.bit.disCur1Prot){
		lastCurErrCode.bit.disCur1Prot = runData.curProtByte.bit.disCur1Prot;
		if(runData.curProtByte.bit.disCur1Prot == 1){
			printf("save DSGOCD over error\n");
			saveErrorRecord(dsgOcdCode);
			append_alarm_prot_record();
		}
	}
	
	if(lastCurErrCode.bit.disCur2Prot != runData.curProtByte.bit.disCur2Prot){
		lastCurErrCode.bit.disCur2Prot = runData.curProtByte.bit.disCur2Prot;
		if(runData.curProtByte.bit.disCur2Prot ==1){
			printf("save DSG 2 over error\n");
			saveErrorRecord(dsgOc2dCode);
			append_alarm_prot_record();
		}
	}
	if(lastCurErrCode.bit.disCur3Prot != runData.curProtByte.bit.disCur3Prot){
		lastCurErrCode.bit.disCur3Prot = runData.curProtByte.bit.disCur3Prot;
		if(runData.curProtByte.bit.disCur3Prot ==1){
			printf("save DSG 3 over error\n");
			saveErrorRecord(dsgOc3dCode);
			append_alarm_prot_record();
		}
	}
	if(lastCurErrCode.bit.disCur4Prot != runData.curProtByte.bit.disCur4Prot){
		lastCurErrCode.bit.disCur4Prot = runData.curProtByte.bit.disCur4Prot;
		if(runData.curProtByte.bit.disCur4Prot ==1){
			printf("save DSG 4 over error\n");
			saveErrorRecord(dsgOc4dCode);
			append_alarm_prot_record();
		}
	}
	if(lastCurErrCode.bit.shortCurProt != runData.curProtByte.bit.shortCurProt){
		lastCurErrCode.bit.shortCurProt = runData.curProtByte.bit.shortCurProt;
		if(runData.curProtByte.bit.shortCurProt == 1){
			printf("save SCD over error\n");
			saveErrorRecord(scdCode);
			append_alarm_prot_record();
		}
	}
	if(lastAfeErrCode.bit.comFaultProt != runData.afeProtByte.bit.comFaultProt){
		lastAfeErrCode.bit.comFaultProt = runData.afeProtByte.bit.comFaultProt;
		if(runData.afeProtByte.bit.comFaultProt == 1){
			printf("save afe communication error\n");
			saveErrorRecord(afeComErrCode);
			append_alarm_prot_record();
		}
	}
	if(lastAfeErrCode.bit.IntFaultProt != runData.afeProtByte.bit.IntFaultProt){
		lastAfeErrCode.bit.IntFaultProt = runData.afeProtByte.bit.IntFaultProt;
		if(runData.afeProtByte.bit.IntFaultProt == 1){
			printf("save afe inside errror\n");
			saveErrorRecord(afeIntErrCode);
			append_alarm_prot_record();
		}
	}
	
	
	
}

